Execute a Loading or Performance Test on ZK using JMeter
Dennis Chen, Senior Engineer, Potix Corporation
January 27, 2012
ZK 6
Introduction
In this small talk, I am going to talk about how you can execute a loading or performance test on ZK applications using JMeter. It not only shows the load on first request to a ZUL page but also the load on subsequence Ajax request in that page. It is always a difficult part to test an Ajax request because of the uuid that is dynamically created. In this article, I will show you the steps of how;
- To write a simple IdGenerator
- Use JMeter to record a request
- Make JMeter testcase replayable
Implementation Steps
To Write a simple IdGenerator
It is important to write a IdGenerator in order to create a predictable desktop id and a component id when testing, then we can record and replay the testcase.
There are two types of ids that needs to be discussed:
1. desktop id - the concept to create a desktop id is that it must be unique in a session and must be passed to subsequent Ajax requests. The idea to provide a predictable desktop id is really simple - 'Server doesn't decide it, testcase do it'
2. component id - the concept to create a component id is that it is not only unique in a scope, but it is also fixed if the component is a 'replay-able target'. For example, when a button is clicked in the testcase, then, the id of the button must be fixed to be replayed. This really depends on your loading testcase target (whether the page creates dynamic number of components or not).
Here, the following code represents a simple sequence in the desktop since my target page creates fixed sequence/number components
public class SequenceIdGenerator implements IdGenerator{
public String nextComponentUuid(Desktop desktop, Component comp) {
String number;
if ((number = (String)desktop.getAttribute("Id_Num")) == null) {
number = "0";
desktop.setAttribute("Id_Num", number);
}
int i = Integer.parseInt(number);
i++;// Start from 1
desktop.setAttribute("Id_Num", String.valueOf(i));
return "t_" + i;
}
public String nextDesktopId(Desktop desktop) {
HttpServletRequest req = (HttpServletRequest)Executions.getCurrent().getNativeRequest();
String dtid = req.getParameter("tdtid");
if(dtid!=null){
//System.out.println(" use client dtid "+dtid); to
}
return dtid==null?null:dtid;
}
public String nextPageUuid(Page page) {
return null;
}
}
To use this generator, we have to add a configuration to zk.xml
<system-config>
<id-generator-class>foo.jmtest.SequenceIdGenerator</id-generator-class>
</system-config>
When an ID generator is introduced to a test environment, the next question is usually how to enable it or disable it depending on the environment. With ZK, it can be done by specifying a library property org.zkoss.zk.config.path
Use JMeter to record a request
Now, I will show you how to RECORD the testcase, please download and install JMeter (version 2.5.1 is used for this article.), then do the following steps;
- Create a Thread Group in Test Plan, name it for example 'Test Search'
- Add User Defined Variables in Test Search
- Add HTTP Cookie Manager in Test Search
- Add HTTP Request Defaults in Test Search
- Edit HTTP Request Defaults, set the Server Name and Port Number (in this case, localhost and 8080) to the application that configured already by
SequenceIdGenerator
- Create a HTTP Proxy Server in WorkBench, and edit it as follows
- Set port to 9090 (or any other port in your control)
- Set Target to Controller to Test Plan > Test Search
- Add Include URL Patterns
- .*/zkau.*
- .*\.zul
- Add Exclude URL Patterns
- .*/zkau/web/.*
- Start the HTTP Proxy Server
Now, you are ready to record the request of the browser to a test case. Please switch the proxy of your browser to host:port (in this case, proxy is localhost:9090), and link to the application (in this case, it is http://localhost:8080/jmtest/search.zul) . I did some selection, textbox typing, and button clicking , you will see not only the first zul request was recorded, but also zkau too. After this has been done, switch the proxy off, and we need to tick off a checklist of the record.
- Check that the uuid of zkau is created by
SequenceIdGenerator
(it will have prefix t_) - Check that there is no
rmDesktop
command in the zkau record, if you have one, please remove it. (It is for removing previous tasks when we recorded the testcase, we don't need it anymore) - Another idea of
rmDesktop
record from this discussion : thread. You could move this record to the end of records, so after each loop of the test, this desktop will be removed, it is a better solution than set max-desktop to 2. - Make sure Server Name and Port Number are recorded in zkau since we already set them in HTTP Request Defaults.
Here are some screenshots
Make JMeter testcase Replayable
To make this testcase replayable, we have to assign the desktop id, following are the steps;
- Add dtid = 0 to User Defined Variables (remember don't add this before you record the testcase, remove this before you re-record the testcase)
- Add a parameter tdtid = ${__intSum(${dtid},1,dtid)} to zul request (in this case, /jmtest/search.zul), tdtid is the parameter that will be checked in
SequenceIdGenerator
- For every zkau request, set the parameter value of dtid to ${dtid} , now the zkau request will send the dtid that we are expecting.
By doing these few steps, we can replay the testcase, but, before that, you have to add some 'Listener and tunning the thread' strategy. To simplify this case , I will just add View Results in Table to Test Search then run the test case. To check whether the testcase is running correctly or not, you can add some logs in you application to see whether or not the action is called.
- Example test result
Other loading test hints
For the loading test to run smoothly, there are some notes I think you should also know.
- Add a Uniform Random Timer to Test Case (set delay to 500ms - 2000ms) to test case, it makes the loading test like a normal access to your application , not a DOS (Deny of Service).
- Server will always crash if you allow a lot of threads to ATTACK it without tunning the server. You have to design a test plan to test your application from light loading to stress loading and analysis the limitation.
- Tune the native server or database configuration if the result is not as expected, there are too many reasons as to why application does not reach expected performance.
- Depending on the test plan, you had better set the max-desktop of ZK to two in order to reduce the memory consumption on the servers of each test thread
Download
Download the JMeter project file here and the target application here
Comments
Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License. |